/**
 * 
 */
package com.unbiz.common.convert.primitive;

import com.unbiz.common.StringUtil;
import com.unbiz.common.convert.ConvertException;
import com.unbiz.common.convert.ObjectConverter;
import com.unbiz.common.convert.TypeConverter;

/**
 * @author <a href="mailto:xuchen06@baidu.com">xuc</a>
 * @version create on 2014年7月28日 下午11:13:01
 */
public class IntegerConverter extends ObjectConverter<Integer> implements TypeConverter<Integer> {

    public IntegerConverter() {
        register(Integer.class);
        register(int.class);
    }

    @Override
    public Integer toConvert(String value) {
        return convert(value);
    }

    @Override
    public String fromConvert(Integer value) {
        return String.valueOf(value);
    }

    public Integer toConvert(Object value) {
        if (value.getClass() == Integer.class) {
            return (Integer) value;
        }
        if (value instanceof Number) {
            return Integer.valueOf(((Number) value).intValue());
        }

        return convert(value.toString());
    }

    private Integer convert(String value) {
    	String stringValue = value.trim();
        if (StringUtil.startsWithChar(stringValue, '+')) {
            stringValue = stringValue.substring(1);
        }
        try {            
            return Integer.valueOf(stringValue);
        } catch (NumberFormatException e) {
        	int i = parseInt(stringValue);
        	if(i==0)
        		throw new ConvertException(value, e);
        	return i;
        }
    }
    


	static public int parseInt(String str) {
		char[] buffer= str.toCharArray();
		int offset = 0; 
		int len = str.length();
		if (len == 0)
			return 0;

		int value = 0;
		int sign = 1;
		boolean isResultSet = false;
		int result = 0;

		int end = offset + len;

		while (offset < end && Character.isWhitespace(buffer[offset])) {
			offset++;
		}

		int ch;
		
		if (offset < end && buffer[offset] == '-') {
			sign = -1;
			offset++;
		} else if (offset < end && buffer[offset] == '+') {
			sign = +1;
			offset++;
		}

		while (offset < end) {
			ch = buffer[offset++];

			if ('0' <= ch && ch <= '9') {
				int newValue = 10 * value + ch - '0';
				if (newValue < value) {
					// php/0143
					// long value overflowed
					result = Integer.MAX_VALUE;
					isResultSet = true;
					break;
				}
				value = newValue;
			} else {
				result = sign * value;
				isResultSet = true;
				break;
			}
		}

		if (!isResultSet)
			result = sign * value;

		return result;
	}


}
